package magicbook.gtlitecore.integration.appliedenergistics2.registration.registry.components;

import appeng.bootstrap.components.IPreInitComponent;
import com.github.bsideup.jabel.Desugar;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import magicbook.gtlitecore.GTLiteCore;
import magicbook.gtlitecore.api.utils.Mods;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.Map;

@SideOnly(Side.CLIENT)
public class AE2BuiltInModelComponent implements IPreInitComponent {

    private final Map<String, IModel> builtInModels = new HashMap<>();
    private boolean hasInitialized = false;

    public AE2BuiltInModelComponent() {}

    /**
     * Add a new Model (at {@code path}).
     * @param path   Model File path.
     * @param model  Model.
     */
    public void addModel(String path, IModel model) {
        //  If model is not initialized, then run.
        Preconditions.checkState(!this.hasInitialized);
        this.builtInModels.put(path, model);
    }

    @Override
    public void preInitialize(Side side) {
        this.hasInitialized = true;
        var loader = new AE2BuiltInModelLoader(this.builtInModels);
        ModelLoaderRegistry.registerLoader(loader);
    }

    @Desugar
    private record AE2BuiltInModelLoader(Map<String, IModel> builtInModels) implements ICustomModelLoader {

            private AE2BuiltInModelLoader(Map<String, IModel> builtInModels) {
                this.builtInModels = ImmutableMap.copyOf(builtInModels);
            }

            @Override
            public boolean accepts(@NotNull ResourceLocation modelLocation) {
                return modelLocation.getNamespace().equals(GTLiteCore.MODID)
                        && this.builtInModels.containsKey(modelLocation.getPath());
            }

            @NotNull
            @Override
            public IModel loadModel(@NotNull ResourceLocation modelLocation) {
                return this.builtInModels.get(modelLocation.getPath());
            }

            //  TODO Find some substitute of IResourceManagerReloadListener.
            @SuppressWarnings("deprecation")
            @Override
            public void onResourceManagerReload(@NotNull IResourceManager resourceManager) {
                for (var model : this.builtInModels.values()) {
                    if (model instanceof IResourceManagerReloadListener) {
                        ((IResourceManagerReloadListener) model).onResourceManagerReload(resourceManager);
                    }
                }
            }
        }

}
